package com.laomou.poker.table;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.laomou.poker.Poker;
import com.laomou.poker.PokerGroup;
import com.laomou.poker.PokerNum;
import com.laomou.poker.player.AbsPlayer;
import com.laomou.poker.rule.IPokerRule;
import com.laomou.poker.rule.PokerRuleFactory;
import com.laomou.poker.rule.PokerRuleType;

public abstract class Table implements ITable {
    /**
     * 桌上的的角色
     */
    private List<AbsPlayer> mPlayer = new ArrayList<AbsPlayer>();
    /**
     * 发牌后剩余的牌
     */
    private List<Poker> mPushPoker = new ArrayList<Poker>();
    /**
     * 桌上所有的牌
     */
    private List<Poker> mTableAllPoker = new ArrayList<Poker>();
    /**
     * 桌上新出的牌
     */
    protected PokerGroup mTableNewPoker;
    /**
     * 扑克牌规则 斗地主 斗牛
     */
    protected IPokerRule mRule;
    /**
     * 开始出牌的角色序号
     */
    private int mStart = 0;
    /**
     * 是否有出错
     */
    private boolean mRunError = false;

    public Table(PokerRuleType type) {
        mRule = PokerRuleFactory.makePokerRule(type);
    }

    /**
     * 添加角色
     */
    public void addPlayer(AbsPlayer pl) {
        pl.setPokerRule(mRule);
        pl.addTable(this);
        mPlayer.add(pl);
    }

    /**
     * 获取角色
     *
     * @param id
     * @return
     */
    protected AbsPlayer getPlayer(int id) {
        return mPlayer.get(id);
    }

    /**
     * 获取角色列表
     *
     * @return
     */
    public List<AbsPlayer> getPlayer() {
        return mPlayer;
    }

    /**
     * 设置开始出牌的角色序号
     *
     * @param start
     */
    public void setStart(int start) {
        this.mStart = start;
    }

    /**
     * 设置是否有异常
     *
     * @param error
     */
    public void setRunError(boolean error) {
        this.mRunError = error;
    }

    /**
     * 获取是否有异常
     *
     * @return
     */
    public boolean getRunError() {
        return mRunError;
    }

    /**
     * 获取发牌后剩余的牌
     *
     * @return
     */
    public List<Poker> getPushPoker() {
        return mPushPoker;
    }

    /**
     * 获取桌子上所有的牌
     *
     * @return
     */
    public List<Poker> getTableAllPoker() {
        return mTableAllPoker;
    }

    /**
     * 添加桌子上的牌
     *
     * @param pg PokerGroup
     */
    public void addTablePoker(PokerGroup pg) {
        for (Poker poker : pg.get()) {
            mTableAllPoker.add(poker);
        }
    }

    /**
     * 获取桌子上新出牌
     *
     * @return
     */
    public PokerGroup getTableNewPoker() {
        return mTableNewPoker;
    }

    /**
     * 获取开始出牌的角色序号
     *
     * @return
     */
    public int getStart() {
        return mStart;
    }

    /**
     * 发牌
     */
    public void onDealPoker() {
        mPushPoker.clear();
        int pcount = mRule.getPokerCount();
        for (PokerNum pn : PokerNum.values()) {
            for (int i = 0; i < pcount; i++) {
                mPushPoker.add(new Poker(pn));
            }
        }
        onPreDealPoker();
        int count = mRule.getPlayerPokerCount();
        Random r = new java.util.Random();
        for (AbsPlayer player : mPlayer) {
            PokerGroup pg = new PokerGroup();
            for (int i = 0; i < count; i++) {
                int n = r.nextInt(mPushPoker.size());
                Poker poker = mPushPoker.get(n);
                pg.addPoker(poker);
                mPushPoker.remove(poker);
            }
            player.addPoker(pg);
        }
    }

    /**
     * 分析牌型
     */
    public void onAnalysePoker() {
        for (AbsPlayer player : mPlayer) {
            player.analysePoker();
        }
    }

    @Override
    public void playGame() {
        onDealPoker();
        onPrePoker();
        if (mRunError) {
            return;
        }
        onAnalysePoker();
        onStart();
    }

    public abstract void onPreDealPoker();

    public abstract void onPrePoker();

    public abstract void onStart();
}
